from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
import time
import threading


class ChromeDriverService:
    """Chrome驱动管理服务类"""
    _driver = dict()
    _lock = threading.Lock()

    @classmethod
    def _create_driver(cls):
        """创建并配置新的Chrome驱动实例"""
        t1 = time.time()
        print('初始化Chrome浏览器...')
        chrome_options = cls._get_chrome_options()
        try:
            driver = webdriver.Chrome(
                options=chrome_options,
                # service=Service(ChromeDriverManager().install())
                service=Service(r'D:\gitee\lvm\chromedriver.exe')
            )

            cls._configure_timeouts(driver)

            print(f'Chrome浏览器初始化完成, 用时 {time.time() - t1:.2f}秒')
            return driver

        except Exception as e:
            print(f"Chrome驱动初始化失败: {e}")
            raise

    @staticmethod
    def _get_chrome_options():
        """配置Chrome选项"""
        chrome_options = Options()

        # 核心优化选项
        # chrome_options.add_argument('--headless')  # 无头模式
        chrome_options.add_argument('--disable-gpu')
        chrome_options.add_argument('--no-sandbox')
        chrome_options.add_argument('--disable-dev-shm-usage')

        # 禁用不必要的功能
        chrome_options.add_argument('--disable-extensions')
        chrome_options.add_argument('--disable-browser-side-navigation')
        chrome_options.add_argument('--disable-javascript')
        chrome_options.add_argument('--disable-plugins')
        chrome_options.add_argument('--disable-images')

        # 性能优化
        chrome_options.add_argument('--window-size=1024,768')
        chrome_options.add_argument('--disk-cache-size=0')
        chrome_options.page_load_strategy = 'none'

        # 设置代理
        # chrome_options.add_argument(f"--proxy-server=192.168.1.212:7890")
        # chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36')

        return chrome_options

    @staticmethod
    def _configure_timeouts(driver):
        """配置驱动超时设置"""
        driver.set_page_load_timeout(6)  # 页面加载超时
        driver.set_script_timeout(6)  # 脚本执行超时
        driver.implicitly_wait(6)  # 隐式等待超时

    @classmethod
    def close_driver(cls, _key='default'):
        driver = cls.get_driver(_key)
        print(f"close_driver")
        try:
            driver.quit()
            print(f"close driver success")
        except Exception as e:
            print(f"关闭Chrome驱动时出错: {e}")
        finally:
            cls._driver[_key] = None

    @classmethod
    def http_get(cls, url, _key='default'):
        driver = ChromeDriverService.get_driver(_key)
        driver.get(url)

        wait = WebDriverWait(driver, timeout=12)
        wait.until(ec.presence_of_element_located((By.TAG_NAME, "body")))  # 等待 body 元素存在
        # wait.until(lambda _driver: _driver.execute_script('return document.readyState') == 'complete')  # 等待页面加载完成
        # wait.until(EC.presence_of_element_located((By.ID, "specific-element-id"))) # 等待特定元素
        time.sleep(1)
        return driver

    @classmethod
    def get_driver(cls, _key='default'):
        """获取或创建Chrome驱动实例"""
        if cls._driver.get(_key) is None:
            with cls._lock:
                if cls._driver.get(_key) is not None:
                    return cls._driver.get(_key)
                cls._driver[_key] = cls._create_driver()

        return cls._driver[_key]


if __name__ == '__main__':
    def f1(k):
        print('f1 run')
        try:
            d = ChromeDriverService.get_driver(k)
            d.get('http://httpbin.org/get')
            time.sleep(1)
            print(d.page_source)
        except Exception as e:
            print(e)
        finally:
            ChromeDriverService.close_driver(k)


    for i in range(3):
        thread = threading.Thread(target=f1, args=(i,)).start()
